package com.inspur.edp.formserver.viewmodel.rtwebapi;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.inspur.edp.bef.bizentity.GspBusinessEntity;
import com.inspur.edp.cef.designtime.api.element.GspElementDataType;
import com.inspur.edp.cef.designtime.api.variable.CommonVariable;
import com.inspur.edp.das.commonmodel.util.HandleAssemblyNameUtil;
import com.inspur.edp.formserver.viewmodel.GspViewModel;
import com.inspur.edp.formserver.viewmodel.common.ConvertUtils;
import com.inspur.edp.formserver.viewmodel.exception.ViewModelException;
import com.inspur.edp.formserver.viewmodel.i18n.VMI8nResourceUtil;
import com.inspur.edp.formserver.viewmodel.i18n.names.VoResourceKeyNames;
import com.inspur.edp.formserver.viewmodel.rtwebapi.exception.VoRtApiErrorCodes;
import com.inspur.edp.formserver.vmmanager.util.CheckInfoUtil;
import com.inspur.edp.formserver.vmmanager.voguide.VoGuideUtil;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.metadata.businesstype.api.MdBizTypeMappingService;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.HashMap;
import java.util.UUID;

@Path("")
@Produces(MediaType.APPLICATION_JSON)
public class VMCodeGenController {

    @Path("convertBizEntity")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public String convertBizEntity(String jsonObject) {
        if (CheckInfoUtil.checkNull(jsonObject)) {
            throw new ViewModelException(VoRtApiErrorCodes.GSP_VIEWOBJECT_RTWEBAPI_1001, null);
        }

        ObjectMapper mapper = new ObjectMapper();
        try {
            JsonNode jsonNode = mapper.readTree(jsonObject);
            JsonNode bizEntityJsonNode = jsonNode.get("bizEntityJson");
            CheckInfoUtil.checkNessaceryInfo("bizEntityJson", bizEntityJsonNode);
            JsonNode bePkgNameJsonNode = jsonNode.get("bePkgName");
            CheckInfoUtil.checkNessaceryInfo("bePkgName", bePkgNameJsonNode);
            JsonNode beIdJsonNode = jsonNode.get("beId");
            CheckInfoUtil.checkNessaceryInfo("beId", beIdJsonNode);
            JsonNode voGeneratingAssemblyJsonNode = jsonNode.get("voGeneratingAssembly");
            CheckInfoUtil.checkNessaceryInfo("voGeneratingAssembly", voGeneratingAssemblyJsonNode);
            String enableProcessItem = "0";
            if (!CheckInfoUtil.checkNull(jsonNode.get("enableProcessItem"))) {
                enableProcessItem = jsonNode.get("enableProcessItem").textValue();
            }

            String bizEntityJson = bizEntityJsonNode.textValue();
            String bePkgName = bePkgNameJsonNode.textValue();
            String beId = beIdJsonNode.textValue();
            String voGeneratingAssembly = voGeneratingAssemblyJsonNode.textValue();

            return convertBizEntityToViewModel(bizEntityJson, bePkgName, beId, voGeneratingAssembly,enableProcessItem);
        } catch (Exception e) {
            throw new ViewModelException(VoRtApiErrorCodes.GSP_VIEWOBJECT_RTWEBAPI_1002, e);
        }

    }

    @Path("createVoRt")
    @PUT
    public String createVoRt(String jsonObject) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            JsonNode jsonNode = mapper.readTree(jsonObject);

            JsonNode basicInfoNode = jsonNode.get("basicInfo");
            CheckInfoUtil.checkNessaceryInfo("basicInfoNode", basicInfoNode);
            String voCode = basicInfoNode.get("code").textValue();
            String voName = basicInfoNode.get("name").textValue();

            JsonNode beNode = jsonNode.get("be");
            CheckInfoUtil.checkNessaceryInfo("beNode", beNode);
            GspBusinessEntity be = mapper.readValue(beNode.toString(), GspBusinessEntity.class);
            CheckInfoUtil.checkNessaceryInfo("be", be);

            GspMetadata beMetadata = VoGuideUtil.getInstance().getRtMetadata(be.getID());
            String beNameSpace = VoGuideUtil.getInstance().getVoMetaGeneratingAssembly(beMetadata);
            String bizObjectId = beMetadata.getHeader().getBizobjectID();

            JsonNode configsArrayNode = jsonNode.get("configs");
            HashMap<String, String> configMap = new HashMap<>();
            if (configsArrayNode != null && configsArrayNode.size() != 0) {
                for (JsonNode configNode : configsArrayNode) {
                    String key = configNode.get("key").textValue();
                    String value = configNode.get("value").textValue();
                    configMap.put(key, value);
                }
            }

            JsonNode billCategoryInfo = jsonNode.get("billCategoryId");
            CheckInfoUtil.checkNessaceryInfo("billCategoryId", billCategoryInfo);
            String billCategoryId = billCategoryInfo.textValue();

            GspViewModel vo = VoGuideUtil.getInstance()
                    .createVo(be, configMap, beNameSpace, HandleAssemblyNameUtil
                            .convertToJavaPackageName(beNameSpace));
            vo.setCode(voCode);
            vo.setName(voName);
            vo.setSource("Print");
            String voId = VoGuideUtil.getInstance().saveVoRt(vo, bizObjectId, beNameSpace);
            MdBizTypeMappingService service = SpringBeanUtils.getBean(MdBizTypeMappingService.class);
            service.save(billCategoryId, voId);
            return new ObjectMapper().writeValueAsString(voId);
        } catch (Exception e) {
            throw new ViewModelException(VoRtApiErrorCodes.GSP_VIEWOBJECT_RTWEBAPI_1003, e);
        }
    }

    @Path("checkVoConfigIdRt")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public void checkVoConfigIdRt(String jsonObject) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            JsonNode jsonNode = mapper.readTree(jsonObject);
            JsonNode beIdNode = jsonNode.get("beId");
            CheckInfoUtil.checkNessaceryInfo("beIdNode", beIdNode);
            String beId = beIdNode.textValue();
            CheckInfoUtil.checkNessaceryInfo("beId", beId);

            JsonNode voCodeNode = jsonNode.get("voCode");
            CheckInfoUtil.checkNessaceryInfo("voCodeNode", voCodeNode);
            String voCode = voCodeNode.textValue();
            CheckInfoUtil.checkNessaceryInfo("voCode", voCode);

            GspMetadata beMetadata = VoGuideUtil.getInstance().getRtMetadata(beId);
            String beNameSpace = VoGuideUtil.getInstance().getVoMetaGeneratingAssembly(beMetadata);
            GspViewModel vo = ConvertUtils
                    .convertToViewModel((GspBusinessEntity) beMetadata.getContent(), beNameSpace,
                            beMetadata.getHeader().getId(),
                            HandleAssemblyNameUtil.convertToJavaPackageName(beNameSpace));
            vo.setCode(voCode);
            VoGuideUtil.getInstance().checkBeforeSave(vo.getGeneratedConfigID(), vo.getId(), vo.getCode());
        } catch (Exception e) {
            throw new ViewModelException(VoRtApiErrorCodes.GSP_VIEWOBJECT_RTWEBAPI_1004, e);
        }
    }

    private String convertBizEntityToViewModel(String bizEntityJson, String bePkgName, String beId,
                                               String voGeneratingAssembly,String enableProcessItem) {
        GspBusinessEntity be = null;
        try {
            be = new ObjectMapper().readValue(bizEntityJson, GspBusinessEntity.class);
            GspViewModel vm = ConvertUtils.convertToViewModel(be, bePkgName, beId, voGeneratingAssembly);
            // 联动vo的关联带出字段枚举信息
//            LinkBeUtils linkBeUtils = new LinkBeUtils();
//            linkBeUtils.LinkBeRefElements(vm);
            if (enableProcessItem.equals("1")) {
                CommonVariable variable = new CommonVariable();
                variable.setID(UUID.randomUUID().toString());
                variable.setCode("bffSysFormConfigId");
                variable.setLabelID("bffSysFormConfigId");
                variable.setName(VMI8nResourceUtil.getMessage(VoResourceKeyNames.FROM_PROCESS_CONFIG));
                variable.setMDataType(GspElementDataType.forValue(0));
                variable.setLength(36);
                vm.getVariables().getContainElements().addField(variable);
            }
            return new ObjectMapper().writeValueAsString(vm);
        } catch (Exception e) {
            throw new ViewModelException(VoRtApiErrorCodes.GSP_VIEWOBJECT_RTWEBAPI_1005, e);
        }
    }
}
